package cn.bonoon.controllers.fmm;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

import javax.servlet.http.HttpServletRequest;

import org.batatasframework.common.ParameterReader;
import org.batatasframework.web.RequestParameterReader;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import cn.bonoon.core.plugins.AccountAssignService;
import cn.bonoon.core.plugins.AccountService;
import cn.bonoon.core.plugins.GroupService;
import cn.bonoon.core.plugins.RoleService;
import cn.bonoon.entities.AccountEntity;
import cn.bonoon.entities.GroupEntity;
import cn.bonoon.entities.RoleEntity;
import cn.bonoon.kernel.menus.MenuCheckable;
import cn.bonoon.kernel.menus.MenuViewBuilder;
import cn.bonoon.kernel.menus.ModuleManager;
import cn.bonoon.kernel.web.controllers.AbstractController;
import cn.bonoon.kernel.web.models.DialogModel;
import cn.bonoon.kernel.web.models.JsonResult;

@Controller
@RequestMapping("s/sys")
public class AccountAssignController extends AbstractController {

//	@Autowired
//	private RoleService roleService;
	@Autowired
	private GroupService groupService;

	@Autowired
	private AccountService accountService;

	@Autowired
	private RoleService roleService;
	
	@Autowired
	private AccountAssignService assignService;
	
	@Autowired
	private ModuleManager moduleManager;

	@RequestMapping(value = "account/!{mid}/groups.load", method = GET)
	public String loadAccountGroups(HttpServletRequest request, Model model,
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id) {
		try{
			//把用户组列出来，可以选择这个用户加入哪些组
			model.addAttribute("groups", assignService.groupsByAccount(id));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-groups-view";
	}

	@RequestMapping(value = "account/!{mid}/groups.do", method = { POST, GET })
	public ModelAndView accountGroups(HttpServletRequest request, 
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id, 
			@RequestParam("gridid") String gridid) {

		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		try{
			AccountEntity account = accountService.get(id);
			model.addObject("name", account.getName() + "[登录名：" + account.getLoginName() + "]");

			//把用户组列出来，可以选择这个用户加入哪些组
			model.addObject("groups", assignService.groups(account));
			
		}catch (Exception e) {
			log(e);
		}
		return model.execute("sys/account/assign-groups");
	}

	@ResponseBody
	@RequestMapping(value = "account/!{mid}/group!save.json", method = POST)
	public final JsonResult saveAccountGroups(HttpServletRequest request, 
			//@PathVariable("mid") String mid, 
			@RequestParam("id") final Long id, 
			@RequestParam(value = "ids", required = false) Long[] ids) {
		try{
			//Long[] roleIds = StringHelper.toLongArray(roles, ",");
			if(null == ids) ids = new Long[0];
			assignService.saveAccountGroups(getUser(), id, ids);
			return JsonResult.result();
		}catch (Exception e) {
			return JsonResult.error(e);
		}
	}

	@RequestMapping(value = "account/!{mid}/authority.load", method = GET)
	public String loadAuthority(HttpServletRequest request, Model model,
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id) {
		try{
			MenuViewBuilder menuBuilder = moduleManager.menuBuilder(MenuCheckable.NONE, true);
			menuBuilder.addAccounts(roleService, id);
			menuBuilder.parse();
			model.addAttribute("privileges", menuBuilder);
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/module-menu-view";
	}


	@RequestMapping(value = "account/!{mid}/roles.load", method = GET)
	public String loadAccountRoles(HttpServletRequest request, Model model,
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id) {
		try{
			model.addAttribute("roles", assignService.rolesByAccount(id));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-roles-view";
	}

	@RequestMapping(value = "account/!{mid}/roles.do", method = { POST, GET })
	public ModelAndView accountRoles(HttpServletRequest request, 
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id, 
			@RequestParam("gridid") String gridid) {
		
		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		try{
			AccountEntity account = accountService.get(id);
			model.addObject("name", account.getName() + "[登录名：" + account.getLoginName() + "]");
			
			// 超级管理员可以分配所有的角色，一般的管理员只允许分配由他创建的那些角色
			model.addObject("roles", assignService.roles(account));
		}catch (Exception e) {
			log(e);
		}
		return model.execute("sys/account/assign-roles");
	}

	@ResponseBody
	@RequestMapping(value = "account/!{mid}/role!save.b", method = POST)
	public final JsonResult saveAccountRoles(HttpServletRequest request, 
			//@PathVariable("mid") String mid, 
			@RequestParam("id") final Long id, 
			@RequestParam(value = "ids", required = false) Long[] ids) {
		try{
			//Long[] roleIds = StringHelper.toLongArray(roles, ",");
			if(null == ids) ids = new Long[0];
			assignService.saveAccountRoles(getUser(), id, ids);
			return JsonResult.result();
		}catch (Exception e) {
			return JsonResult.error(e);
		}
	}

	@RequestMapping(value = "group/!{mid}/roles.do", method = { POST, GET })
	public ModelAndView groupRoles(HttpServletRequest request, 
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id, 
			@RequestParam("gridid") String gridid) {
		
		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		try{
			GroupEntity group = groupService.get(id);
			model.addObject("name", group.getName());
			
			// 超级管理员可以分配所有的角色，一般的管理员只允许分配由他创建的那些角色
			model.addObject("roles", assignService.roles(group));
		}catch (Exception e) {
			log(e);
		}
		return model.execute("sys/account/assign-roles");
	}

	@ResponseBody
	@RequestMapping(value = "group/!{mid}/role!save.b", method = POST)
	public final JsonResult saveGroupRoles(HttpServletRequest request, 
			//@PathVariable("mid") String mid, 
			@RequestParam("id") final Long id, 
			@RequestParam(value = "ids", required = false) Long[] ids) {
		try{
			//Long[] roleIds = StringHelper.toLongArray(roles, ",");
			if(null == ids) ids = new Long[0];
			assignService.saveGroupRoles(getUser(), id, ids);
			return JsonResult.result();
		}catch (Exception e) {
			return JsonResult.error(e);
		}
	}

	@RequestMapping(value = "role/!{mid}/groups.do", method = { POST, GET })
	public ModelAndView roleGroups(HttpServletRequest request, 
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id, 
			@RequestParam("gridid") String gridid) {

		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		try{
			RoleEntity role = roleService.get(id);
			model.addObject("name", role.getName());

			//把用户组列出来，可以选择这个用户加入哪些组
			model.addObject("groups", assignService.groups(role));
			
		}catch (Exception e) {
			log(e);
		}
		return model.execute("sys/account/assign-groups");
	}

	@ResponseBody
	@RequestMapping(value = "role/!{mid}/group!save.b", method = POST)
	public final JsonResult saveRoleGroups(
			@RequestParam("id") final Long id, 
			@RequestParam(value = "ids", required = false) Long[] ids) {
		try{
			//Long[] roleIds = StringHelper.toLongArray(roles, ",");
			if(null == ids) ids = new Long[0];
			assignService.saveRoleGroups(getUser(), id, ids);
			return JsonResult.result();
		}catch (Exception e) {
			return JsonResult.error(e);
		}
	}
	
	@RequestMapping(value = "account/search.do", method = POST)
	public String accountSearch(HttpServletRequest request, Model model){
		try{
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/account-search";
	}

	@RequestMapping(value = "role/privileges.json", method = { POST, GET })
	public String privileges(Model model, @RequestParam("rid") Long rid) {
		try{
			MenuViewBuilder builder = moduleManager.menuBuilder(MenuCheckable.READONLY, false);
			
			builder.addRoles(roleService, rid);
			
			model.addAttribute("privileges", builder.parse());
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/module-menu-editable";
	}
	
//	private List<Node> visitMenus(List<MenuInfo> menus, String parentId, List<String> selectedIds) {
//		if (null == menus || menus.isEmpty()) return null;
//		
//		List<Node> nodes = new ArrayList<Node>(); // 菜单节点
//		for (MenuInfo mi : menus) {
//			String mid = mi.getId();
//			Node _node = new Node(mid, mi.getName(), parentId);
//			
//			
//			if(selectedIds.contains(mid)){
//				_node.setChecked(true);
//				_node.setIconCls("icon-accept");
//				nodes.add(_node);
//			}else if(getUser().isSuper()) {
//				nodes.add(_node);
//			}else{
//				continue;
//			}
//			// 子菜单节点
//			List<Node> children = visitMenus(mi.getMenus(), mid, selectedIds); // 递归子菜单
//			if (null != children && !children.isEmpty()) {
//				_node.setChildren(children);
//			}
//		}
//		return nodes;
//	}

	@RequestMapping(value = "role/!{mid}/account!search.do", method = POST)
	public String searchRoleAccounts(HttpServletRequest request, Model model){
		try{
			ParameterReader parameter = RequestParameterReader.valueOf(request);
			model.addAttribute("assigns", assignService.searchRoleAccounts(parameter));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-accounts-search";
	}

	@RequestMapping(value = "group/!{mid}/account!search.do", method = POST)
	public String searchGroupAccounts(HttpServletRequest request, Model model){
		try{
			ParameterReader parameter = RequestParameterReader.valueOf(request);
			model.addAttribute("assigns", assignService.searchGroupAccounts(parameter));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-accounts-search";
	}

	@RequestMapping(value = "role/!{mid}/account!delete.do", method = POST)
	public String deleteRoleAccounts(HttpServletRequest request, Model model){
		try{
			ParameterReader parameter = RequestParameterReader.valueOf(request);
			model.addAttribute("assigns", assignService.deleteRoleAccounts(parameter));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-accounts-search";
	}

	@RequestMapping(value = "group/!{mid}/account!delete.do", method = POST)
	public String deleteGroupAccounts(HttpServletRequest request, Model model){
		try{
			ParameterReader parameter = RequestParameterReader.valueOf(request);
			model.addAttribute("assigns", assignService.deleteGroupAccounts(parameter));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-accounts-search";
	}

	@RequestMapping(value = "role/!{mid}/account!save.do", method = POST)
	public String saveRoleAccounts(HttpServletRequest request, Model model){
		try{
			ParameterReader parameter = RequestParameterReader.valueOf(request);
			model.addAttribute("assigns", assignService.saveRoleAccounts(parameter));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-accounts-search";
	}

	@RequestMapping(value = "group/!{mid}/account!save.do", method = POST)
	public String saveGroupAccounts(HttpServletRequest request, Model model){
		try{
			ParameterReader parameter = RequestParameterReader.valueOf(request);
			model.addAttribute("assigns", assignService.saveGroupAccounts(parameter));
		}catch (Exception e) {
			log(e);
		}
		model.addAttribute("layout", "layout-empty.vm");
		return "sys/account/assign-accounts-search";
	}

	@RequestMapping(value = "role/!{mid}/accounts.do", method = { POST, GET })
	public ModelAndView roleAccounts(HttpServletRequest request, 
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id, 
			@RequestParam("gridid") String gridid) {

		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		try{
			RoleEntity role = roleService.get(id);
			model.addObject("name", role.getName());

			//把用户组列出来，可以选择这个用户加入哪些组
			model.addObject("assigns", assignService.accounts(role, 0));
			
		}catch (Exception e) {
			log(e);
		}
		return model.execute("sys/account/assign-accounts");
	}

	@RequestMapping(value = "group/!{mid}/accounts.do", method = { POST, GET })
	public ModelAndView groupAccounts(HttpServletRequest request, 
			@PathVariable("mid") String mid, 
			@RequestParam("id") Long id, 
			@RequestParam("gridid") String gridid) {

		DialogModel model = new DialogModel(mid, request);
		model.addForm(id);
		model.addObject("gridid", gridid);
		model.addObject("id", id);
		try{
			GroupEntity group = groupService.get(id);
			model.addObject("name", group.getName());

			//把用户组列出来，可以选择这个用户加入哪些组
			model.addObject("assigns", assignService.accounts(group, 0));
			
		}catch (Exception e) {
			log(e);
		}
		return model.execute("sys/account/assign-accounts");
	}

}
